import 'dart:async';
import 'dart:math';
import 'package:bruno/bruno.dart';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;

class KqTable<T extends ITableData> extends StatefulWidget {
  /// 控件数据
  final List<List<T>> data;

  /// 文本大小
  final double fontSize;

  /// 文本颜色
  final Color textColor;

  /// 控件宽度
  final double? width;

  /// 控件高度
  final double? height;

  /// 表格颜色
  final Color tableColor;

  /// 表格边框颜色
  final Color tableBorderColor;

  /// 表格点击选中颜色
  final Color tableClickChosenColor;

  /// 表格长按选中颜色
  final Color tableLongPressChosenColor;

  /// 表格点击选中边框颜色
  final Color tableClickChosenBorderColor;

  /// 表格长按选中边框颜色
  final Color tableLongPressChosenBorderColor;

  /// 上下左右固定行数值[int,int,int,int]
  final List<int> lockList;

  /// 指定特定行或者列的颜色，行使用[RowColor],列使用[ColumnColor]
  final List<TableColor> colorList;

  /// 点击单元格回调
  final Function(T data)? onTap;

  /// 是否上下滑动刷新

  /// 手指滑动到达上下边缘
  /// canVerticalScroll是否垂直方向可滑动
  final Function(bool canVerticalScroll)? verticalScroll;
  final Function(bool canHorizontalScroll)? horizontalScroll;

  /// 惯性滑动到达上下边缘
  final Function(Direction direction)? inertiaScrollToDirection;

  const KqTable(
      {super.key,
      required this.data,
      this.fontSize = 14,
      this.textColor = Colors.black,
      this.width,
      this.height,
      this.tableColor = Colors.white,
      this.tableBorderColor = const Color.fromARGB(255, 189, 189, 189),
      this.lockList = const [1, 0, 1, 0],
      this.colorList = const [
        RowColor(0, Color.fromARGB(255, 238, 238, 238)),
        ColumnColor(0, Color.fromARGB(255, 238, 238, 238))
      ],
      this.onTap,
      this.tableClickChosenColor =
          const Color.fromARGB(102, 130, 177, 255), //a=40% blue
      this.tableClickChosenBorderColor =
          const Color.fromARGB(230, 130, 177, 255), //90% blue
      this.tableLongPressChosenColor =
          const Color.fromARGB(102, 29, 233, 182), //a=40% green
      this.tableLongPressChosenBorderColor =
          const Color.fromARGB(230, 29, 233, 182),
      this.verticalScroll,
      this.horizontalScroll,
      this.inertiaScrollToDirection}); //a=90% green

  @override
  State<StatefulWidget> createState() => _KqTableState<T>();
}

class _KqTableState<T extends ITableData> extends State<KqTable<T>>
    with TickerProviderStateMixin {
  /// 长按判定等待时间100毫秒
  final int _waitTime = 100;

  /// x方向偏移量
  double _offsetDx = 0;

  /// y方向偏移量
  double _offsetDy = 0;

  /// x方向误差量
  double _diffOffsetDx = 0;

  /// y方向误差量
  double _diffOffsetDy = 0;

  /// 行数
  int _xLength = 0;

  /// 列数
  int _yLength = 0;

  /// 每列的行文本最大宽度列表[[原宽度,调整后宽度],[原宽度,调整后宽度],...]
  final List<List<double>> _xWidthList = [];

  /// 每行的文本高度，高度也可以变化，所以不能用一个值表达[[原高度，调整后高度],[原高度，调整后高度],...]
  final List<List<double>> _yHeightList = [];

  /// 按下时当前单元格的对象
  T? _opTableData;

  /// 当前手势是否滑动
  bool _opIsMove = false;

  /// 当前是否是长按
  bool _opIsLongPress = false;

  /// 绘制对象缓存
  final List<ITableData> _tempDrawData = <ITableData>[];

  /// 计时器
  Timer? timer;

  /// 点击选中行
  int _opClickChosenX = -1;

  /// 点击选中列
  int _opClickChosenY = -1;

  /// 长按选中行
  int _opLongPressChosenX = -1;

  /// 长按选中的行或者列的宽度或者高度值;
  double _opLongPressChosenWH = 0;

  /// 长按选中列
  int _opLongPressChosenY = -1;

  /// 点击是否同时选中行列
  bool _opIsClickChosenXY = false;

  /// 长按是否同时选中行列
  bool _opIsLongPressChosenXY = false;

  AnimationController? _animationControllerX;
  Animation<double>? _animationX;

  //手指移动的位置
  double _lastMoveX = 0.0;
  double directionX = 0;
  double distanceX = 0;

  AnimationController? _animationControllerY;
  Animation<double>? _animationY;

  //手指移动的位置
  double _lastMoveY = 0.0;
  double directionY = 0;
  double distanceY = 0;

  double width = 0, height = 0;

  @override
  void initState() {
    super.initState();
    _initData();
  }

  @override
  void dispose() {
    //退出时关闭计时器防止内存泄露
    _stopLongPressTimer();
    _animationControllerX?.dispose();
    _animationControllerY?.dispose();
    super.dispose();
  }

  void _initData() {
    _xLength = widget.data[0].length;
    _yLength = widget.data.length;
    double columnHeight = 0;
    for (int i = 0; i < _xLength; i++) {
      double maxWidth = 0;
      for (int j = 0; j < _yLength; j++) {
        ITableData tableData = widget.data[j][i];
        TextPainter textPainter = TextPainter(
            text: TextSpan(
                text: tableData.text,
                style: TextStyle(
                    color: widget.textColor, fontSize: widget.fontSize)),
            maxLines: 1,
            textDirection: TextDirection.ltr)
          ..layout(minWidth: 0, maxWidth: double.infinity);
        if (maxWidth < textPainter.width) {
          maxWidth = textPainter.width;
        }
        columnHeight = textPainter.height;
      }
      _xWidthList.add([maxWidth, maxWidth]);
    }
    for (int j = 0; j < _yLength; j++) {
      _yHeightList.add([columnHeight, columnHeight]);
    }
  }

  void _startLongPressTimer(VoidCallback callback) {
    //计时器，每[_waitTime]毫秒执行一次
    var period = Duration(milliseconds: _waitTime);
    if (timer != null && timer!.isActive) {
      timer?.cancel();
    }
    timer = Timer(period, () {
      if (mounted) {
        _opIsLongPress = true;
        callback();
      }
    });
  }

  void _stopLongPressTimer() {
    timer?.cancel();
  }

  void _yCallBack(canVerticalScroll, canHorizontalScroll, direction) {
    if (canVerticalScroll != null) {
      widget.verticalScroll?.call(canVerticalScroll);
    }
    if (canHorizontalScroll != null) {
      widget.horizontalScroll?.call(canHorizontalScroll);
    }
  }

  @override
  Widget build(BuildContext context) {
    return getTableWidget();
  }

  Widget getTableWidget() {
    return LayoutBuilder(
      builder: (context, container) {
        width = widget.width ?? container.maxWidth;
        height = widget.height ?? container.maxHeight;
        return RepaintBoundary(
          child: ClipRect(
            child: Listener(
              child: Listener(
                child: CustomPaint(
                  size: Size(width, height),
                  painter: _TablePainter(
                      this,
                      _offsetDx,
                      _offsetDy,
                      widget.data,
                      _xLength,
                      _yLength,
                      _xWidthList,
                      _yHeightList,
                      _tempDrawData,
                      _opClickChosenX,
                      _opClickChosenY,
                      _opLongPressChosenX,
                      _opLongPressChosenY,
                      _opIsClickChosenXY,
                      _opIsLongPressChosenXY,
                      width,
                      height),
                ),
                onPointerDown: (PointerDownEvent event) {
                  _yCallBack(false, false, null);
                  _opIsMove = false;
                  _opIsLongPress = false;
                  _opIsLongPressChosenXY = false;
                  _opIsClickChosenXY = false;
                  _opLongPressChosenX = -1;
                  _opLongPressChosenY = -1;
                  _opClickChosenX = -1;
                  _opClickChosenY = -1;
                  //事件点击的中心位置
                  Offset? eventOffset = event.localPosition;
                  _diffOffsetDx = eventOffset.dx - _offsetDx;
                  _diffOffsetDy = eventOffset.dy - _offsetDy;

                  ///判定按下在哪个单元格，并获取单元格内容
                  //点击的横向坐标
                  int y = 0;
                  //点击的纵向坐标
                  int x = 0;
                  //计算横向和纵向坐标
                  ITableData? tempX;
                  ITableData? tempY;
                  for (ITableData tableData in _tempDrawData) {
                    if (eventOffset.dx < (tableData.left! + tableData.width!) &&
                        eventOffset.dx >= tableData.left!) {
                      if (tempX == null || tempX.level! < tableData.level!) {
                        tempX = tableData;
                      }
                    }

                    if (eventOffset.dy < (tableData.top! + tableData.height!) &&
                        eventOffset.dy >= tableData.top!) {
                      if (tempY == null || tempY.level! < tableData.level!) {
                        tempY = tableData;
                      }
                    }
                  }
                  if (tempX != null) {
                    x = tempX.x!;
                  }
                  if (tempY != null) {
                    y = tempY.y!;
                  }
                  // 单击单元格判定
                  if (x == 0 && y == 0) {
                    _opIsClickChosenXY = true;
                  } else if (x == 0) {
                    _opClickChosenY = y;
                  } else if (y == 0) {
                    _opClickChosenX = x;
                  } else {
                    _opIsClickChosenXY = false;
                    _opClickChosenX = -1;
                    _opClickChosenY = -1;
                  }
                  //获取坐标对应的值
                  _opTableData = widget.data[y][x];

                  /// 长按拖拽判定
                  _startLongPressTimer(() {
                    if (y == 0 && x != 0) {
                      // 判断宽度拖拽
                      _opLongPressChosenX = x;
                      _opLongPressChosenWH =
                          _xWidthList[_opLongPressChosenX][1];
                    } else if (x == 0 && y != 0) {
                      //判断高度拖拽
                      _opLongPressChosenY = y;
                      _opLongPressChosenWH =
                          _yHeightList[_opLongPressChosenY][1];
                    } else if (y == 0 && x == 0) {
                      //判断宽度和高度同时拖拽
                      _opIsLongPressChosenXY = true;
                    }
                    if (_opLongPressChosenX != -1 ||
                        _opLongPressChosenY != -1 ||
                        _opIsLongPressChosenXY) {
                      _opClickChosenX = -1;
                      _opClickChosenY = -1;
                      _opIsClickChosenXY = false;
                    }
                    setState(() {});
                  });
                },
                onPointerMove: (PointerMoveEvent event) {
                  _opIsMove = true;
                  _stopLongPressTimer();
                  //事件点击的中心位置
                  Offset? eventOffset = event.localPosition;
                  bool isScrollTopOrDown = false;
                  bool isScrollLeftOrRight = false;
                  if (_opLongPressChosenX != -1) {
                    ///表格宽度拖拽
                    if (_xWidthList[_opLongPressChosenX][1] >
                            _xWidthList[_opLongPressChosenX][0] ||
                        ((eventOffset.dx - _diffOffsetDx) > 0 &&
                            _xWidthList[_opLongPressChosenX][1] ==
                                _xWidthList[_opLongPressChosenX][0])) {
                      _xWidthList[_opLongPressChosenX][1] =
                          _opLongPressChosenWH + eventOffset.dx - _diffOffsetDx;
                    } else {
                      _xWidthList[_opLongPressChosenX][1] =
                          _xWidthList[_opLongPressChosenX][0];
                    }
                  } else if (_opLongPressChosenY != -1) {
                    ///表格高度拖拽
                    if (_yHeightList[_opLongPressChosenY][1] >
                            _yHeightList[_opLongPressChosenY][0] ||
                        ((eventOffset.dy - _diffOffsetDy) > 0 &&
                            _yHeightList[_opLongPressChosenY][1] ==
                                _yHeightList[_opLongPressChosenY][0])) {
                      _yHeightList[_opLongPressChosenY][1] =
                          _opLongPressChosenWH + eventOffset.dy - _diffOffsetDy;
                    } else {
                      _yHeightList[_opLongPressChosenY][1] =
                          _yHeightList[_opLongPressChosenY][0];
                    }
                  } else if (_opIsLongPressChosenXY) {
                    ///宽高同时拖拽
                    if (eventOffset.dx >= _xWidthList[0][0]) {
                      _xWidthList[0][1] = eventOffset.dx;
                    } else {
                      _xWidthList[0][1] = _xWidthList[0][0];
                    }
                    if (eventOffset.dy >= _yHeightList[0][0]) {
                      _yHeightList[0][1] = eventOffset.dy;
                    } else {
                      _yHeightList[0][1] = _yHeightList[0][0];
                    }
                  } else {
                    ///表格移动
                    _offsetDx = eventOffset.dx - _diffOffsetDx;
                    _offsetDy = eventOffset.dy - _diffOffsetDy;
                  }

                  /// 边界处理
                  // 当有固定行时
                  // 上边限定
                  if (_offsetDy >= 0) {
                    _offsetDy = 0;
                    _yCallBack(true, null, Direction.top);
                    isScrollTopOrDown = true;
                  }
                  // 左边限定
                  if (_offsetDx >= 0) {
                    _offsetDx = 0;
                    _yCallBack(null, true, Direction.left);
                    isScrollLeftOrRight = true;
                  }
                  // 右边限定
                  double rightOffset = 0;
                  double tableWidth =
                      _TableUtils.getTableRealWidth(_xWidthList);
                  double tableHeight =
                      _TableUtils.getTableRealHeight(_yHeightList);
                  for (int i = 0; i < widget.lockList[3]; i++) {
                    rightOffset += _xWidthList[_xWidthList.length - i - 1][1];
                  }
                  if (_offsetDx <= (width + rightOffset) - tableWidth) {
                    _offsetDx = (width + rightOffset) - tableWidth;
                    _yCallBack(null, true, Direction.right);
                    isScrollLeftOrRight = true;
                  }
                  // 下边限定
                  List<double> reversalCellHeights =
                      _TableUtils.reversalCellHeights(_yLength, _yHeightList);
                  if (_offsetDy <=
                      (height +
                              reversalCellHeights[widget.lockList[1] == 0
                                  ? 0
                                  : widget.lockList[1] - 1]) -
                          tableHeight) {
                    _offsetDy = (height +
                            reversalCellHeights[widget.lockList[1] == 0
                                ? 0
                                : widget.lockList[1] - 1]) -
                        tableHeight;
                    _yCallBack(true, null, Direction.bottom);
                    isScrollTopOrDown = true;
                  }
                  //当表格宽度小于控件宽度，则不能水平移动
                  if (tableWidth <= width) {
                    _offsetDx = 0;
                    _yCallBack(null, true, null);
                    isScrollLeftOrRight = true;
                  }
                  //当表格高度小于控件高度，则不能上下移动
                  if (tableHeight <= height) {
                    _offsetDy = 0;
                    _yCallBack(true, null, null);
                    isScrollTopOrDown = true;
                  }

                  if (!isScrollTopOrDown || !isScrollLeftOrRight) {
                    setState(() {});
                  }
                },
                onPointerUp: (PointerUpEvent event) {
                  if (_opIsLongPress) {
                    //长按
                    setState(() {
                      _opLongPressChosenX = -1;
                      _opLongPressChosenY = -1;
                      _opIsLongPressChosenXY = false;
                    });
                  } else if (!_opIsMove) {
                    //单击
                    setState(() {
                      _stopLongPressTimer();
                      widget.onTap?.call(_opTableData as T);
                    });
                  } else if (_opIsMove) {
                    _yCallBack(true, true, null);
                  }
                },
              ),
              onPointerDown: (event) {
                _animationControllerX?.stop(canceled: true);
                _animationControllerY?.stop(canceled: true);
              },
              onPointerMove: (event) {
                //速率
                distanceY = sqrt(event.delta.dy * event.delta.dy);

                //手指移动的距离
                var positionY = event.position.dy;
                //判断距离差，方向
                directionY = positionY - _lastMoveY;
                _lastMoveY = positionY;

                //速率
                distanceX = sqrt(event.delta.dx * event.delta.dx);

                //手指移动的距离
                var positionX = event.position.dx;
                //判断距离差，方向
                directionX = positionX - _lastMoveX;
                _lastMoveX = positionX;
              },
              onPointerUp: (event) {
                startAnimationX();
                startAnimationY();
              },
            ),
          ),
        );
      },
    );
  }

  void startAnimationY() {
    if (directionY == 0 || distanceY < 1) {
      return;
    }
    _animationControllerY = AnimationController(
        duration: const Duration(milliseconds: 200), vsync: this);
    _animationControllerY?.addListener(() {
      bool isScrollTopOrDown = false;
      _offsetDy = _animationY!.value;

      /// 边界处理
      // 当有固定行时
      // 上边限定
      if (_offsetDy >= 0) {
        _offsetDy = 0;
        isScrollTopOrDown = true;
      }
      // 左边限定
      if (_offsetDx >= 0) {
        _offsetDx = 0;
      }
      // 右边限定
      double rightOffset = 0;
      double tableWidth = _TableUtils.getTableRealWidth(_xWidthList);
      double tableHeight = _TableUtils.getTableRealHeight(_yHeightList);
      for (int i = 0; i < widget.lockList[3]; i++) {
        rightOffset += _xWidthList[_xWidthList.length - i - 1][1];
      }
      if (_offsetDx <= (width + rightOffset) - tableWidth) {
        _offsetDx = (width + rightOffset) - tableWidth;
      }
      // 下边限定
      List<double> reversalCellHeights =
          _TableUtils.reversalCellHeights(_yLength, _yHeightList);
      if (_offsetDy <=
          (height +
                  reversalCellHeights[
                      widget.lockList[1] == 0 ? 0 : widget.lockList[1] - 1]) -
              tableHeight) {
        _offsetDy = (height +
                reversalCellHeights[
                    widget.lockList[1] == 0 ? 0 : widget.lockList[1] - 1]) -
            tableHeight;
        isScrollTopOrDown = true;
      }
      //当表格宽度小于控件宽度，则不能水平移动
      if (tableWidth <= width) {
        _offsetDx = 0;
      }
      //当表格高度小于控件高度，则不能上下移动
      if (tableHeight <= height) {
        _offsetDy = 0;
        isScrollTopOrDown = true;
      }

      if (isScrollTopOrDown) {
        if (directionY > 0) {
          widget.inertiaScrollToDirection?.call(Direction.top);
        } else {
          widget.inertiaScrollToDirection?.call(Direction.bottom);
        }
      }

      if (!isScrollTopOrDown) {
        setState(() {});
      }
    });
    _animationY = CurvedAnimation(
        parent: _animationControllerY!, curve: Curves.decelerate);
    _animationY = Tween(
            begin: _offsetDy,
            end: directionY > 0
                ? _offsetDy + distanceY * 15
                : _offsetDy - distanceY * 15)
        .animate(_animationY!);
    _animationControllerY?.forward();
  }

  void startAnimationX() {
    if (directionX == 0 || distanceX < 1) {
      return;
    }
    _animationControllerX = AnimationController(
        duration: const Duration(milliseconds: 200), vsync: this);
    _animationControllerX?.addListener(() {
      bool isScrollLeftOrRight = false;
      _offsetDx = _animationX!.value;

      /// 边界处理
      // 当有固定行时
      // 上边限定
      if (_offsetDy >= 0) {
        _offsetDy = 0;
      }
      // 左边限定
      if (_offsetDx >= 0) {
        _offsetDx = 0;
        isScrollLeftOrRight = true;
      }
      // 右边限定
      double rightOffset = 0;
      double tableWidth = _TableUtils.getTableRealWidth(_xWidthList);
      double tableHeight = _TableUtils.getTableRealHeight(_yHeightList);
      for (int i = 0; i < widget.lockList[3]; i++) {
        rightOffset += _xWidthList[_xWidthList.length - i - 1][1];
      }
      if (_offsetDx <= (width + rightOffset) - tableWidth) {
        _offsetDx = (width + rightOffset) - tableWidth;
        isScrollLeftOrRight = true;
      }
      // 下边限定
      List<double> reversalCellHeights =
          _TableUtils.reversalCellHeights(_yLength, _yHeightList);
      if (_offsetDy <=
          (height +
                  reversalCellHeights[
                      widget.lockList[1] == 0 ? 0 : widget.lockList[1] - 1]) -
              tableHeight) {
        _offsetDy = (height +
                reversalCellHeights[
                    widget.lockList[1] == 0 ? 0 : widget.lockList[1] - 1]) -
            tableHeight;
      }
      //当表格宽度小于控件宽度，则不能水平移动
      if (tableWidth <= width) {
        _offsetDx = 0;
        isScrollLeftOrRight = true;
      }
      //当表格高度小于控件高度，则不能上下移动
      if (tableHeight <= height) {
        _offsetDy = 0;
      }

      if (isScrollLeftOrRight) {
        if (directionX > 0) {
          widget.inertiaScrollToDirection?.call(Direction.left);
        } else {
          widget.inertiaScrollToDirection?.call(Direction.right);
        }
      }

      if (!isScrollLeftOrRight) {
        setState(() {});
      }
    });
    _animationX = CurvedAnimation(
        parent: _animationControllerX!, curve: Curves.decelerate);
    _animationX = Tween(
            begin: _offsetDx,
            end: directionX > 0
                ? _offsetDx + distanceX * 15
                : _offsetDx - distanceX * 15)
        .animate(_animationX!);
    _animationControllerX?.forward();
  }
}

class _TablePainter<T> extends CustomPainter {
  /// state
  final _KqTableState state;

  /// x方向偏移量
  final double _offsetDx;

  /// y方向偏移量
  final double _offsetDy;

  final List<List<T>>? _data;

  /// 行数
  final int _xLength;

  /// 列数
  final int _yLength;

  /// 每列的行文本最大宽度列表
  final List<List<double>> _xWidthList;

  /// 每行的文本高度列表
  final List<List<double>> _columnHeightList;

  /// 绘制对象缓存
  final List<ITableData> _tempDrawData;

  /// 点击选中行
  final int _opClickChosenX;

  /// 点击选中列
  final int _opClickChosenY;

  /// 长按选中行
  final int _opLongPressChosenX;

  /// 长按选中列
  final int _opLongPressChosenY;

  /// 点击是否同时选中行列
  final bool _opIsClickChosenXY;

  /// 长按是否同时选中行列
  final bool _opIsLongPressChosenXY;

  final double _width;
  final double _height;

  _TablePainter(
      this.state,
      this._offsetDx,
      this._offsetDy,
      this._data,
      this._xLength,
      this._yLength,
      this._xWidthList,
      this._columnHeightList,
      this._tempDrawData,
      this._opClickChosenX,
      this._opClickChosenY,
      this._opLongPressChosenX,
      this._opLongPressChosenY,
      this._opIsClickChosenXY,
      this._opIsLongPressChosenXY,
      this._width,
      this._height);

  @override
  void paint(Canvas canvas, Size size) {
    //表格边框画笔
    final Paint paint1 = Paint()
      ..strokeCap = StrokeCap.square
      ..isAntiAlias = true
      ..style = PaintingStyle.stroke
      ..color = state.widget.tableBorderColor;
    //表格背景画笔
    final Paint paint2 = Paint()
      ..strokeCap = StrokeCap.square
      ..isAntiAlias = true
      ..style = PaintingStyle.fill
      ..color = state.widget.tableColor;

    _tempDrawData.clear();
    drawTable(canvas, size, paint1, paint2);
  }

  void drawTable(Canvas canvas, Size size, Paint paint1, Paint paint2) {
    List<double> reversalRowWidths =
        _TableUtils.reversalCellWidths(_xLength, _xWidthList);
    List<double> reversalColumnHeights =
        _TableUtils.reversalCellHeights(_yLength, _columnHeightList);
    double totalCellWidth = 0;
    double cellWidth = 0;
    for (int i = 0; i < _xLength; i++) {
      totalCellWidth += cellWidth;
      cellWidth = _xWidthList[i][1];
      double totalCellHeight = 0;
      double cellHeight = 0;
      if (totalCellWidth + _offsetDx <= _width) {
        for (int j = 0; j < _yLength; j++) {
          String str = (_data![j][i] as ITableData).text;
          totalCellHeight += cellHeight;
          cellHeight = _columnHeightList[j][1];
          if (totalCellHeight + _offsetDy <= _height) {
            if (j < state.widget.lockList[0]) {
              //上
              if (i < state.widget.lockList[2]) {
                //左上角
                drawTableAdd(str, totalCellWidth, totalCellHeight, cellWidth,
                    cellHeight, j, i,
                    level: 2);
              } else if (i >= _xLength - state.widget.lockList[3]) {
                //右上角
                drawTableAdd(str, _width - reversalRowWidths[_xLength - i - 1],
                    totalCellHeight, cellWidth, cellHeight, j, i,
                    level: 2);
              } else {
                drawTableAdd(str, totalCellWidth + _offsetDx, totalCellHeight,
                    cellWidth, cellHeight, j, i,
                    level: 1);
              }
            } else if (i < state.widget.lockList[2]) {
              //左
              if (j >= _yLength - state.widget.lockList[1]) {
                //左下角
                drawTableAdd(
                    str,
                    totalCellWidth,
                    _height - reversalColumnHeights[_yLength - j - 1],
                    cellWidth,
                    cellHeight,
                    j,
                    i,
                    level: 2);
              } else {
                drawTableAdd(str, totalCellWidth, totalCellHeight + _offsetDy,
                    cellWidth, cellHeight, j, i,
                    level: 1);
              }
            } else if (j >= _yLength - state.widget.lockList[1]) {
              //下
              if (i >= _xLength - state.widget.lockList[3]) {
                // 右下角
                drawTableAdd(
                    str,
                    _width - reversalRowWidths[_xLength - i - 1],
                    _height - reversalColumnHeights[_yLength - j - 1],
                    cellWidth,
                    cellHeight,
                    j,
                    i,
                    level: 2);
              } else {
                drawTableAdd(
                    str,
                    totalCellWidth + _offsetDx,
                    _height - reversalColumnHeights[_yLength - j - 1],
                    cellWidth,
                    cellHeight,
                    j,
                    i,
                    level: 1);
              }
            } else if (i >= _xLength - state.widget.lockList[3]) {
              //右
              drawTableAdd(str, _width - reversalRowWidths[_xLength - i - 1],
                  totalCellHeight + _offsetDy, cellWidth, cellHeight, j, i,
                  level: 1);
            } else {
              drawTableAdd(str, totalCellWidth + _offsetDx,
                  totalCellHeight + _offsetDy, cellWidth, cellHeight, j, i);
            }
          }
        }
      }
    }

    drawTableReal(canvas, size, paint1, paint2);
  }

  /// 把需要绘制的数据先放入内存中
  void drawTableAdd(String text, double left, double top, double width,
      double height, int y, int x,
      {int? level}) {
    if (top <= _height && left <= _width) {
      _tempDrawData.add(ITableData(text,
          left: left,
          top: top,
          width: width,
          height: height,
          y: y,
          x: x,
          level: level ?? 0));
    }
  }

  /// 遍历存好的数据进行绘制
  void drawTableReal(Canvas canvas, Size size, Paint paint1, Paint paint2) {
    //绘制层级排序
    _tempDrawData.sort((a, b) => a.level!.compareTo(b.level!));
    //绘制
    for (ITableData data in _tempDrawData) {
      if (data.top! <= _height && data.left! <= _width) {
        //构建文字
        ui.ParagraphBuilder paragraphBuilder =
            ui.ParagraphBuilder(ui.ParagraphStyle())
              ..pushStyle(ui.TextStyle(
                  color: state.widget.textColor,
                  fontSize: state.widget.fontSize))
              ..addText(data.text);
        //先初始化paint2的颜色
        paint2.color = state.widget.tableColor;
        //表格有指定颜色的颜色
        if (state.widget.colorList.isNotEmpty) {
          for (TableColor tableColor in state.widget.colorList) {
            if (tableColor is RowColor && tableColor.index == data.y) {
              paint2.color = tableColor.color;
            } else if (tableColor is ColumnColor &&
                tableColor.index == data.x) {
              paint2.color = tableColor.color;
            }
          }
        }

        ///画表格背景
        canvas.drawRect(
            Rect.fromLTWH(data.left!, data.top!, data.width!, data.height!),
            paint2);

        //画笔颜色调整，主要针点击背景覆盖层和边框绘制
        if ((_opLongPressChosenX != -1 && data.x == _opLongPressChosenX) ||
            (_opLongPressChosenY != -1 && data.y == _opLongPressChosenY) ||
            (_opIsLongPressChosenXY && (data.x == 0 || data.y == 0))) {
          paint2.color = state.widget.tableLongPressChosenColor;
          paint1.color = state.widget.tableLongPressChosenBorderColor;

          ///画表格覆盖背景
          canvas.drawRect(
              Rect.fromLTWH(data.left!, data.top!, data.width!, data.height!),
              paint2);
        } else if ((_opClickChosenX != -1 && data.x == _opClickChosenX) ||
            (_opClickChosenY != -1 && data.y == _opClickChosenY) ||
            (_opIsClickChosenXY && (data.x == 0 || data.y == 0))) {
          paint2.color = state.widget.tableClickChosenColor;
          paint1.color = state.widget.tableClickChosenBorderColor;

          ///画表格覆盖背景
          canvas.drawRect(
              Rect.fromLTWH(data.left!, data.top!, data.width!, data.height!),
              paint2);
        }

        ///画表格边框
        canvas.drawRect(
            Rect.fromLTWH(data.left!, data.top!, data.width!, data.height!),
            paint1);

        ///画表格文本
        canvas.drawParagraph(
            paragraphBuilder.build()
              ..layout(ui.ParagraphConstraints(width: size.width)),
            Offset(data.left!, data.top!));
      }
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

abstract class TableColor {
  final int index;
  final Color color;

  const TableColor(this.index, this.color);
}

class RowColor extends TableColor {
  const RowColor(super.index, super.color);
}

class ColumnColor extends TableColor {
  const ColumnColor(super.index, super.color);
}

class ITableData {
  final String text;
  double? left;
  double? top;
  double? width;
  double? height;
  int? y;
  int? x;
  int? level = 0;

  ITableData(this.text,
      {this.left,
      this.top,
      this.width,
      this.height,
      this.y,
      this.x,
      this.level});

  @override
  String toString() {
    return "text=$text,left=$left,top=$top,width=$width,height=$height,row=$y,column=$x,level=$level";
  }
}

class _TableUtils {
  /// 单元格宽度反向长度列表
  static List<double> reversalCellWidths(
      int xLength, List<List<double>> xWidthList) {
    List<double> totalReversalCellWidthList = [];
    double totalReversalCellWidth = 0;
    for (int i = xLength - 1; i >= 0; i--) {
      totalReversalCellWidth += xWidthList[i][1];
      totalReversalCellWidthList.add(totalReversalCellWidth);
    }
    return totalReversalCellWidthList;
  }

  /// 单元格高度反向高度列表
  static List<double> reversalCellHeights(
      int yLength, List<List<double>> yHeightList) {
    List<double> totalReversalCellHeightList = [];
    double totalReversalCellHeight = 0;
    for (int i = yLength - 1; i >= 0; i--) {
      totalReversalCellHeight += yHeightList[i][1];
      totalReversalCellHeightList.add(totalReversalCellHeight);
    }
    return totalReversalCellHeightList;
  }

  /// 获取表格宽高
  static double getTableRealWidth(List<List<double>> xWidthList) {
    double totalWidth = 0;
    for (int i = 0; i < xWidthList.length; i++) {
      totalWidth += xWidthList[i][1];
    }
    return totalWidth;
  }

  /// 获取表格宽高
  static double getTableRealHeight(List<List<double>> yHeightList) {
    double totalHeight = 0;
    for (int i = 0; i < yHeightList.length; i++) {
      totalHeight += yHeightList[i][1];
    }
    return totalHeight;
  }
}
